﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using Infraestructure.CrossCutting.NetFramework.Resources;
using System.Text.RegularExpressions;
using Infraestructure.CrossCutting.Security;

namespace Infraestructure.CrossCutting.NetFramework.Security
{
    /// <summary>
    /// Implemantacion de la interfaz IMembershipManager usando MembershipProvider de Microsoft
    /// </summary>
    public sealed class MembershipManager 
        : IMembershipManager
    {
        #region Private

        private const string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                          @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                          @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";

        private Regex re;

        #endregion

        #region Constructor

        public MembershipManager()
        {
            re = new Regex(strRegex);
        }

        #endregion

        #region CreateUser

        public MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password", Messages.exception_InvalidPassword);
            }

            if (String.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email", Messages.exception_InvalidEmail);
            }

            if (!re.IsMatch(email))
            {
                throw new ArgumentException("email", Messages.exception_InvalidEmail);
            }

            if (String.IsNullOrEmpty(passwordQuestion))
            {
                throw new ArgumentNullException("passwordQuestion", Messages.exception_InvalidQuestion);
            }

            if (String.IsNullOrEmpty(passwordAnswer))
            {
                throw new ArgumentNullException("passwordAnswer", Messages.exception_InvalidAnswer);
            }

            MembershipCreateStatus status;
            MembershipUser user = Membership.CreateUser(username, password, email, passwordQuestion, passwordAnswer, true, out status);
            if (status == MembershipCreateStatus.Success)
            {
                return user;
            }
            return null;
        }

        public MembershipUser CreateUser(string username, string password)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password", Messages.exception_InvalidPassword);
            }

            return Membership.CreateUser(username, password);
        }

        public MembershipUser CreateUser(string username, string password, string email)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password", Messages.exception_InvalidPassword);
            }

            if (String.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email", Messages.exception_InvalidEmail);
            }

            if (!re.IsMatch(email))
            {
                throw new ArgumentException("email", Messages.exception_InvalidEmail);
            }


            return Membership.CreateUser(username, password, email);
        }

        #endregion

        #region ValidateUser

        public bool ValidateUser(string username, string password)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            if (String.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password", Messages.exception_InvalidPassword);
            }

            return Membership.ValidateUser(username, password);
        }

        #endregion

        #region GetUser

        public MembershipUser User
        {
            get { return Membership.GetUser(); }
        }

        public MembershipUser GetUser(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            return Membership.GetUser(username, false);
        }

        public MembershipUser GetUser(object providerUserKey)
        {
            return Membership.GetUser(providerUserKey, false);
        }

        #endregion

        #region ProviderUserKey

        public object ProviderUserKey
        {
            get { return Membership.GetUser().ProviderUserKey; }
        }

        public object GetProviderUserKey(string username)
        {
            MembershipUser user = Membership.GetUser(username);
            if (user == null)
            {
                throw new ArgumentNullException("user", Messages.exception_InvalidUser);
            }

            return user.ProviderUserKey;
        }

        #endregion

        #region FindUsers

        public MembershipUserCollection FindUsers(string emailOrName)
        {
            if (string.IsNullOrEmpty(emailOrName))
            {
                return Membership.GetAllUsers();
            }

            if (emailOrName.Contains('@'))
            {
                return Membership.FindUsersByEmail(emailOrName);
            }

            return Membership.FindUsersByName(emailOrName);
        }

        #endregion

        #region Password

        public string ResetPassword(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }

            MembershipUser user = Membership.GetUser(username);

            if (user == null)
            {
                throw new ArgumentNullException("user", Messages.exception_InvalidUser);
            }

            return user.ResetPassword();
        }

        #endregion

        #region DeleteUser

        public bool DeleteUser(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }


            return Membership.DeleteUser(username);
        }

        #endregion

        #region UnlockUser

        public bool UnlockUser(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username", Messages.exception_InvalidUserName);
            }


            MembershipUser user = Membership.GetUser(username);

            if (user == null)
            {
                throw new ArgumentNullException("user", Messages.exception_InvalidUser);
            }

            return user.UnlockUser();

        }

        #endregion

        #region UpdateUser

        public void UpdateUser(MembershipUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user", Messages.exception_InvalidUser);
            }

            Membership.UpdateUser(user);
        }

        #endregion
    }
}
